#include <functional>
#include <list>
namespace detail {
    template<typename Sender, typename SourceMessageType = typename Sender::value_type, typename MessageType = typename SourceMessageType::value_type>
    class join_impl {
        public:
            using value_type = MessageType;

            join_impl(Sender &&sender)
                : m_sender(std::move(sender))
            {
            }

            template <typename EmitFunction>
            void on_message(EmitFunction emit)
            {
                m_emit = emit;
                m_sender.on_message(
                    [this] (SourceMessageType &&message)
                        {
                            process_message(std::move(message));
                        }
                    );
            }

            void process_message(SourceMessageType&& source)
            {
                // 当监听到新的流时，保存它的消息
                m_sources.emplace_back(std::move(source));
                m_sources.back().set_message_handler(m_emit);
            }
            private:
                Sender m_sender;
                std::function<void<MessageType&&> m_emit;
                std::list<SourceMessageType> m_sources;

    };
    
    struct join_helper {
    };
}

template <typename Sender>
auto join(Sender&& sender)
{
    return detail::join_impl<Sender>(std::forward<Sender>(sender));
}